mod entity;
mod event;
mod module;

use crate::app::cluster::Cluster;
use crate::app::core::entity::Entity;
use crate::app::htp::build_http_entry_point;
use crate::config::{Config, EPType, EntryPoint, IngressLister, ServicesLister};
pub use anyhow::Result;
pub use event::*;
pub use module::*;
use std::sync::Arc;

pub async fn start(cfg: Config) -> Result<Entity> {
    let ety = Entity::new(build, cfg.entry_points)?;
    register_dispenser(cfg.ingress, cfg.services, Arc::new(ety.clone())).await?;
    Ok(ety)
}

fn build(ep: EntryPoint) -> Result<(Box<dyn EntryPointServer>, Box<dyn ControlPanel>)> {
    match ep.ty.clone() {
        EPType::Http => {
            let (s, r) = build_http_entry_point(ep)?;
            Ok((Box::new(s), Box::new(r)))
        }
        _ => Err(anyhow::anyhow!("不支持的接入类型[{:?}]", ep.ty)),
    }
}

async fn register_dispenser<T: ControlEventDispenser>(
    ing_lister_cfg: IngressLister,
    svc_lister_cfg: ServicesLister,
    dispenser: Arc<T>,
) -> Result<()> {
    let cluster = Cluster::try_default(ing_lister_cfg, svc_lister_cfg).await?;
    cluster.active_service_watch(dispenser.clone())?;
    cluster.active_ingress_watch(dispenser.clone())
}
